package com.git.hui.yinshua.biz.rest.app.order;

import com.git.hui.yinshua.api.model.CntDto;
import com.git.hui.yinshua.api.model.ExceptionUtil;
import com.git.hui.yinshua.api.model.ListRsp;
import com.git.hui.yinshua.api.model.ReqInfoContext;
import com.git.hui.yinshua.api.model.ResVo;
import com.git.hui.yinshua.api.model.Status;
import com.git.hui.yinshua.api.model.order.OrderStatusEnum;
import com.git.hui.yinshua.api.model.order.OrderTypeEnum;
import com.git.hui.yinshua.api.model.permission.Permission;
import com.git.hui.yinshua.api.model.permission.UserAccessRole;
import com.git.hui.yinshua.biz.order.service.AppOrderService;
import com.git.hui.yinshua.biz.order.service.OrderService;
import com.git.hui.yinshua.biz.order.service.PtOrderService;
import com.git.hui.yinshua.biz.pay.service.PaymentService;
import com.git.hui.yinshua.biz.rest.models.order.req.OrderCreateReq;
import com.git.hui.yinshua.biz.rest.models.order.req.OrderQueryReq;
import com.git.hui.yinshua.biz.rest.models.order.rsp.OrderDto;
import com.git.hui.yinshua.biz.rest.models.order.rsp.PaymentDto;
import com.google.common.base.Splitter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 小程序，下单
 *
 * @author YiHui
 * @date 2024/6/18
 */
@Slf4j
@RestController
@RequestMapping(path = "app/order")
@Permission(role = UserAccessRole.LOGIN)
public class OrderController {
    @Autowired
    private AppOrderService appOrderService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private PtOrderService ptOrderService;
    @Autowired
    private PaymentService paymentService;


    /**
     * 下单
     *
     * @param req
     * @return
     */
    @RequestMapping(path = "add")
    public ResVo<PaymentDto> createOrder(@RequestBody OrderCreateReq req) {
        req.setUserId(ReqInfoContext.getReqInfo().getUserId());
        Long oid;
        if (Objects.equals(req.getType(), OrderTypeEnum.PT.getType())) {
            // 拼团单
            oid = appOrderService.createPtOrder(req);
        } else {
            // 普通订单
            oid = appOrderService.createOrder(req);
        }

        try {
            return ResVo.ok(paymentService.genPayment(oid));
        } catch (Exception e) {
            log.error("支付单创建失败: {}", oid, e);
            // 支付创建失败，直接进入详情
            PaymentDto dto = new PaymentDto();
            dto.setOrderId(oid);
            return new ResVo<>(dto);
        }
    }

    /**
     * 订单列表
     *
     * @param status
     * @param page
     * @param size
     * @return
     */
    @GetMapping(path = "list")
    public ResVo<ListRsp<OrderDto>> list(@RequestParam(name = "status", required = false) String status, @RequestParam(name = "page") Integer page, @RequestParam(name = "size") Integer size) {
        OrderQueryReq req = new OrderQueryReq();
        req.setPage(page);
        req.setSize(size);
        req.setUserId(ReqInfoContext.getReqInfo().getUserId());
        // 过滤已删除的订单
        req.setDeleted(0);
        if (StringUtils.isNotBlank(status) && !"null".equals(status)) {
            req.setState(Splitter.on(",").splitToStream(status).map(Integer::valueOf).collect(Collectors.toList()));
        }
        ListRsp<OrderDto> list = orderService.list(req);
        return ResVo.ok(list);
    }

    /**
     * 订单详情
     *
     * @param orderId
     * @return
     */
    @GetMapping(path = "detail")
    public ResVo<OrderDto> detail(@RequestParam("orderId") Long orderId) {
        OrderDto order = orderService.detail(orderId);
        if (OrderTypeEnum.PT.getType().equals(order.getType())) {
            order.setPtOrder(ptOrderService.queryPtOrderByOrderId(order.getOrderId()));
        }
        return ResVo.ok(order);
    }

    /**
     * 去支付
     *
     * @param orderId 订单id
     * @return 支付信息
     */
    @GetMapping(path = "toPay")
    public ResVo<PaymentDto> toPay(@RequestParam("orderId") Long orderId) {
        return ResVo.ok(paymentService.genPayment(orderId));
    }

    @GetMapping(path = "delete")
    public ResVo<Boolean> removeOrder(@RequestParam("orderId") Long orderId) {
        return ResVo.ok(orderService.deleteOrder(orderId));
    }

    /**
     * 订单更新: 主要是更新订单的收货地址、商品选中的图片
     *
     * @return
     */
    @RequestMapping(path = "update")
    public ResVo<Boolean> update(@RequestBody OrderCreateReq req) {
        if (req.getOrderId() == null) {
            throw ExceptionUtil.of(Status.StatusEnum.ILLEGAL_ARGUMENTS_MIXED, "缺少需要更新的订单信息");
        }

        return ResVo.ok(appOrderService.updateOrderInfo(req));
    }

    /**
     * 前端标记已经支付成功，只更新订单状态为已支付，订单的支付状态，更新为支付中
     *
     * @param orderId 订单id
     * @return
     */
    @GetMapping(path = "markPay")
    public ResVo<Boolean> paySucceed(@RequestParam("orderId") Long orderId) {
        return ResVo.ok(paymentService.paying(orderId));
    }

    /**
     * 查询各订单状态数量
     *
     * @return
     */
    @GetMapping(path = "orderCnt")
    public ResVo<List<CntDto>> listOrderCnt() {
        OrderQueryReq req = new OrderQueryReq();
        req.setUserId(ReqInfoContext.getReqInfo().getUserId());
        req.setState(Arrays.asList(OrderStatusEnum.TO_PAY.getStatus(),
                OrderStatusEnum.PT_ING.getStatus(),
                OrderStatusEnum.TO_EXPRESS.getStatus(),
                OrderStatusEnum.TO_SIGN.getStatus()));
        req.setDeleted(0);
        return ResVo.ok(orderService.listCntByStatus(req));
    }
}
